﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using APH.Parl2.Shared.Tests.ParlInfoService;

namespace APH.Parl2.Shared.Tests.ParlInfoOdataAPI
{
    [TestClass]
    public class EntityQueriesTests
    {
        EntityQueries eq;

        public EntityQueriesTests()
        {
            eq = new EntityQueries();
        }
        private TestContext testContextInstance;
        public TestContext TestContext
        {
            get { return testContextInstance; }
            set { testContextInstance = value; }
        }

        #region Bills

        [DataSource("BillsDataSource"),
        TestMethod()]
        public void BillsTest()
        {

            string kw = TestContext.DataRow["keyword"] as string;
            bool? titleOnlySearch = TestContext.DataRow["titleOnlySearch"] as bool?;
            DateTime? fromDate = TestContext.DataRow["fromDate"] as DateTime?;
            DateTime? toDate = TestContext.DataRow["toDate"] as DateTime?;
            int? parliamentNumber = TestContext.DataRow["parliamentNumber"] as int?;
            string status = Convert.ToString(TestContext.DataRow["status"]);
            string type = Convert.ToString(TestContext.DataRow["type"]);
            int? expectedCount = Convert.ToInt16(TestContext.DataRow["expectedCount"]);

            var bs = eq.Bills(kw, titleOnlySearch, fromDate, toDate,parliamentNumber,status,type);

            //anticipated result
            if (expectedCount != null)
            {
                Assert.IsTrue(bs.Count() == expectedCount, "{0} results expected, {1} returned.", expectedCount, bs.Count());
            }

            foreach (Bill b in bs)
            {
                //keyword search
                if (kw != null && kw != "")
                {
                    if (titleOnlySearch == true)
                    {
                        Assert.IsTrue(b.Title.ToLower().Contains(kw) == true,
                            String.Format("Title does not contain the '{0}' keyword searched for.", kw));
                    }
                    else
                    {
                        Assert.IsTrue(b.Title.ToLower().Contains(kw) == true || b.IndexedContent.ToLower().Contains(kw) == true,
                            String.Format("Indexed content or title does not contain the '{0}' keyword searched for.", kw));
                    }
                }

                //dates
                if (fromDate != null && toDate != null)
                {
                    Assert.IsTrue(b.Date >= fromDate && b.Date <= toDate,
                        "Bill date {0} not in range provided ({1} - {2}).",
                        fromDate, toDate);
                }

            }
        }

        [DataSource("BillsByFirstLetterDataSource"), 
        TestMethod()]
        public void BillsByFirstLetterTest()
        {
            
            string firstLetter = Convert.ToString(testContextInstance.DataRow["firstLetter"]);
            int? expectedCount = Convert.ToInt16(TestContext.DataRow["expectedCount"]);

            var bills = eq.BillsByFirstLetter(firstLetter);

            //anticipated result count
            if (expectedCount != null)
            {
                Assert.IsTrue(bills.Count() == expectedCount, "{0} results expected, {1} returned.", expectedCount, bills.Count());
            }

        }
        
        
        #endregion

        #region BillsDigests

        #endregion

        #region TariffProposals
        [DataSource("TariffProposalsDataSource"),
        TestMethod()]
        public void TariffProposalsTest()
        {
            string type = Convert.ToString(testContextInstance.DataRow["Type"]);
            int? expectedCount = Convert.ToInt16(TestContext.DataRow["expectedCount"]);

            var tps = eq.TariffProposals(type);

            //anticipated result count
            if (expectedCount != null)
            {
                Assert.IsTrue(tps.Count() == expectedCount, "{0} results expected, {1} returned.", expectedCount, tps.Count());
            }

            // check that the collection has the attributes searched for
            foreach (TariffProposal tp in tps)
            {
                if (type != null && type != "")
                {
                    Assert.IsTrue(tp.Type == type,
                        "Tariff Proposal type '{0}' not equal to type searched for '{1}'.", tp.Type, type);
                }

                Assert.IsNotNull(tp.Id);
                Assert.IsNotNull(tp.Title);
                Assert.IsNotNull(tp.Date);
                Assert.IsNotNull(tp.Summary);
                Assert.IsNotNull(tp.Link);

            }
        }
        #endregion

        #region Publications
        [DataSource("PublicationsDataSource"),
        TestMethod()]
        public void PublicationsTest()
        {
            string keyword = TestContext.DataRow["keyword"] as string;
            bool? titleOnlySearch = TestContext.DataRow["titleOnlySearch"] as bool?;
            DateTime? fromDate = TestContext.DataRow["fromDate"] as DateTime?;
            DateTime? toDate = TestContext.DataRow["toDate"] as DateTime?;
            string publishingArea = TestContext.DataRow["publishingArea"] as string;;
            int? expectedCount = Convert.ToInt16(TestContext.DataRow["expectedCount"]);

            var pubs = eq.Publications(keyword, titleOnlySearch, fromDate, toDate, publishingArea);

            //anticipated result
            if (expectedCount != null)
            {
                Assert.IsTrue(pubs.Count() == expectedCount, "{0} results expected, {1} returned.", expectedCount, pubs.Count());
            }

            // check that the collection has the attributes searched for
            foreach (Publication p in pubs)
            {
                //keyword search
                if (keyword != null && keyword != "")
                {
                    if (titleOnlySearch == true)
                    {
                        Assert.IsTrue(p.Title.ToLower().Contains( keyword ),
                            "Keyword '{0}' not found in title.");
                    }else{
                        Assert.IsTrue(p.Title.ToLower().Contains(keyword) || p.IndexedContent.ToLower().Contains(keyword),
                            "Keyword '{0}' not found in title or content.");
                    }
                }
                // dates
                if (toDate != null && fromDate != null)
                {
                    Assert.IsTrue(toDate > fromDate, "'To' date must be after 'from' date.");
                    Assert.IsTrue(fromDate <= p.Date,
                        "Publication date {0} before from date {1}.",
                        p.Date.ToShortDateString(),
                        fromDate);
                    Assert.IsTrue(toDate >= p.Date,
                        "Publication date {0} after to date {1}.",
                        p.Date.ToShortDateString(),
                        toDate);
                }
                //publishing area
                if (publishingArea != null && publishingArea != "")
                {
                    Assert.IsTrue(p.PublishingArea == publishingArea,
                        "Publishing area '{0}' does not equal {1}.",
                        p.PublishingArea, publishingArea);
                }
            }
        }
        [DataSource("LibraryPublicationsDataSource"), 
            TestMethod()]
        public void LibraryPublicationsTest()
        {
            // TODO - replace with data driven parameters
            string keyword = TestContext.DataRow["keyword"] as string;
            string publicationType = TestContext.DataRow["publicationType"] as string;
            string keywordSearchType = TestContext.DataRow["keywordSearchType"] as string;
            DateTime? fromDate = TestContext.DataRow["fromDate"] as DateTime?;
            DateTime? toDate = TestContext.DataRow["toDate"] as DateTime?;
            int? expectedCount = Convert.ToInt16(TestContext.DataRow["expectedCount"]);


            var lps = eq.LibraryPublications(keyword,
                publicationType,
                fromDate,
                toDate,
                keywordSearchType);

            //anticipated result
            if (expectedCount != null)
            {
                Assert.IsTrue(lps.Count() == expectedCount, "{0} results expected, {1} returned.", expectedCount, lps.Count());
            }

            // check that the collection has the attributes searched for
            foreach (Publication p in lps)
            {
                //keyword search
                if (keyword != "")
                {
                    switch (keywordSearchType)
                    {
                        case "All":
                            Assert.IsTrue(
                            p.IndexedContent.ToLower().Contains(keyword) ||
                            p.Title.ToLower().Contains(keyword) ||
                            p.Authors.ToLower().Contains(keyword), "Keyword '{0}' not found in content, authors or title.", keyword);
                            break;
                        case "Author":
                            Assert.IsTrue(p.Authors.ToLower().Contains(keyword), "Keyword '{0}' not found in authors.", keyword);
                            break;
                        case "Title":
                            Assert.IsTrue(p.Title.ToLower().Contains(keyword), "Keyword '{0}' not found in authors.", keyword);
                            break;
                    }
                }

                //dates
                if (toDate != null && fromDate != null)
                {
                    Assert.IsTrue(toDate > fromDate, "'To' date must be after 'from' date.");
                    Assert.IsTrue(fromDate <= p.Date,
                        "Publication date {0} before from date {1}.",
                        p.Date.ToShortDateString(),
                        fromDate);
                    Assert.IsTrue(toDate >= p.Date,
                        "Publication date {0} after to date {1}.",
                        p.Date.ToShortDateString(),
                        toDate);
                }
                //publication type
                if (publicationType == null || publicationType == "All")
                {
                    Assert.IsTrue(p.PublicationType == "Library Publication" || p.PublicationType == "Bills Digest",
                        "Publication is of the wrong type ({0}).", p.PublicationType);
                }
                else
                {
                    Assert.IsTrue(p.PublicationType == publicationType,
                        "Publication is of the wrong type ({0}), should be {1}.",
                        p.PublicationType, publicationType);
                }
            }

        } 
        #endregion

    }
}
